package com.smart.community.region.service.impl;

import java.util.Collections;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

import com.smart.community.commons.cache.DataScopeInfo;
import com.smart.community.feign.property.service.DataScopeFeign;
import com.smart.community.region.service.DataScopeService;

import lombok.extern.slf4j.Slf4j;

/**
 * 数据权限服务实现类
 * 
 * 重要修复说明（2025-01-30）：
 * - 移除getUserDataScope方法的@Cacheable注解，避免DataScopeInfo复杂对象序列化/反序列化时的ClassCastException问题
 * - 复杂对象（如DataScopeInfo、自定义VO、复杂实体类等）在Redis缓存中容易出现类型转换错误
 * - 遵循《Java后端SpringBoot代码开发规范.md》的缓存使用规范
 * 
 * @author Wu.Liang
 * @since 2024-12-21
 * @version 1.1.0
 */
@Slf4j
@Service
public class DataScopeServiceImpl implements DataScopeService {
    
    @Autowired
    private DataScopeFeign dataScopeFeign;
    
    @Override
    @Cacheable(value = "datascope:regionIds", key = "#userId", unless = "#result == null || #result.isEmpty()")
    public List<Long> getAccessibleRegionIds(Long userId) {
        long startTime = System.currentTimeMillis();
        log.info("获取用户可访问的区域ID列表，用户ID：{}", userId);
        
        try {
            // 参数验证
            if (userId == null) {
                log.warn("用户ID为空，返回空列表");
                return Collections.emptyList();
            }
            
            DataScopeInfo dataScopeInfo = dataScopeFeign.getUserDataScope(userId);
            if (dataScopeInfo == null) {
                log.warn("获取用户数据权限信息失败，用户ID：{}", userId);
                return Collections.emptyList();
            }
            
            // 超级管理员可以访问所有区域
            if (dataScopeInfo.isSuperAdmin()) {
                // 这里应该返回所有区域ID，但为了简化，暂时返回空列表
                // 实际实现中应该查询所有区域ID
                long endTime = System.currentTimeMillis();
                log.info("超级管理员获取区域ID列表完成，用户ID：{}，耗时：{}ms", userId, endTime - startTime);
                return Collections.emptyList();
            }
            
            // 普通用户通过社区获取区域ID
            List<Long> communityIds = dataScopeInfo.getCommunityIds();
            if (communityIds == null || communityIds.isEmpty()) {
                long endTime = System.currentTimeMillis();
                log.info("用户无社区权限，用户ID：{}，耗时：{}ms", userId, endTime - startTime);
                return Collections.emptyList();
            }
            
            // 这里应该根据社区ID查询对应的区域ID
            // 为了简化，暂时返回空列表
            long endTime = System.currentTimeMillis();
            log.info("获取用户可访问的区域ID列表完成，用户ID：{}，耗时：{}ms", userId, endTime - startTime);
            return Collections.emptyList();
            
        } catch (Exception e) {
            long endTime = System.currentTimeMillis();
            log.error("获取用户可访问的区域ID列表失败，用户ID：{}，耗时：{}ms", userId, endTime - startTime, e);
            return Collections.emptyList();
        }
    }
    
    @Override
    @Cacheable(value = "datascope:communityIds", key = "#userId", unless = "#result == null || #result.isEmpty()")
    public List<Long> getAccessibleCommunityIds(Long userId) {
        long startTime = System.currentTimeMillis();
        log.info("获取用户可访问的社区ID列表，用户ID：{}", userId);
        
        try {
            // 参数验证
            if (userId == null) {
                log.warn("用户ID为空，返回空列表");
                return Collections.emptyList();
            }
            
            DataScopeInfo dataScopeInfo = dataScopeFeign.getUserDataScope(userId);
            if (dataScopeInfo == null) {
                log.warn("获取用户数据权限信息失败，用户ID：{}", userId);
                return Collections.emptyList();
            }
            
            List<Long> result = dataScopeInfo.getCommunityIds() != null ? dataScopeInfo.getCommunityIds() : Collections.emptyList();
            long endTime = System.currentTimeMillis();
            log.info("获取用户可访问的社区ID列表完成，用户ID：{}，数量：{}，耗时：{}ms", userId, result.size(), endTime - startTime);
            return result;
            
        } catch (Exception e) {
            long endTime = System.currentTimeMillis();
            log.error("获取用户可访问的社区ID列表失败，用户ID：{}，耗时：{}ms", userId, endTime - startTime, e);
            return Collections.emptyList();
        }
    }
    
    @Override
    @Cacheable(value = "datascope:buildingIds", key = "#userId", unless = "#result == null || #result.isEmpty()")
    public List<Long> getAccessibleBuildingIds(Long userId) {
        long startTime = System.currentTimeMillis();
        log.info("获取用户可访问的楼栋ID列表，用户ID：{}", userId);
        
        try {
            // 参数验证
            if (userId == null) {
                log.warn("用户ID为空，返回空列表");
                return Collections.emptyList();
            }
            
            DataScopeInfo dataScopeInfo = dataScopeFeign.getUserDataScope(userId);
            if (dataScopeInfo == null) {
                log.warn("获取用户数据权限信息失败，用户ID：{}", userId);
                return Collections.emptyList();
            }
            
            // 超级管理员可以访问所有楼栋
            if (dataScopeInfo.isSuperAdmin()) {
                // 这里应该返回所有楼栋ID，但为了简化，暂时返回空列表
                long endTime = System.currentTimeMillis();
                log.info("超级管理员获取楼栋ID列表完成，用户ID：{}，耗时：{}ms", userId, endTime - startTime);
                return Collections.emptyList();
            }
            
            // 普通用户通过社区获取楼栋ID
            List<Long> communityIds = dataScopeInfo.getCommunityIds();
            if (communityIds == null || communityIds.isEmpty()) {
                long endTime = System.currentTimeMillis();
                log.info("用户无社区权限，用户ID：{}，耗时：{}ms", userId, endTime - startTime);
                return Collections.emptyList();
            }
            
            // 这里应该根据社区ID查询对应的楼栋ID
            // 为了简化，暂时返回空列表
            long endTime = System.currentTimeMillis();
            log.info("获取用户可访问的楼栋ID列表完成，用户ID：{}，耗时：{}ms", userId, endTime - startTime);
            return Collections.emptyList();
            
        } catch (Exception e) {
            long endTime = System.currentTimeMillis();
            log.error("获取用户可访问的楼栋ID列表失败，用户ID：{}，耗时：{}ms", userId, endTime - startTime, e);
            return Collections.emptyList();
        }
    }
    
    @Override
    @Cacheable(value = "datascope:unitIds", key = "#userId", unless = "#result == null || #result.isEmpty()")
    public List<Long> getAccessibleUnitIds(Long userId) {
        long startTime = System.currentTimeMillis();
        log.info("获取用户可访问的单元ID列表，用户ID：{}", userId);
        
        try {
            // 参数验证
            if (userId == null) {
                log.warn("用户ID为空，返回空列表");
                return Collections.emptyList();
            }
            
            DataScopeInfo dataScopeInfo = dataScopeFeign.getUserDataScope(userId);
            if (dataScopeInfo == null) {
                log.warn("获取用户数据权限信息失败，用户ID：{}", userId);
                return Collections.emptyList();
            }
            
            // 超级管理员可以访问所有单元
            if (dataScopeInfo.isSuperAdmin()) {
                // 这里应该返回所有单元ID，但为了简化，暂时返回空列表
                long endTime = System.currentTimeMillis();
                log.info("超级管理员获取单元ID列表完成，用户ID：{}，耗时：{}ms", userId, endTime - startTime);
                return Collections.emptyList();
            }
            
            // 普通用户通过社区获取单元ID
            List<Long> communityIds = dataScopeInfo.getCommunityIds();
            if (communityIds == null || communityIds.isEmpty()) {
                long endTime = System.currentTimeMillis();
                log.info("用户无社区权限，用户ID：{}，耗时：{}ms", userId, endTime - startTime);
                return Collections.emptyList();
            }
            
            // 这里应该根据社区ID查询对应的单元ID
            // 为了简化，暂时返回空列表
            long endTime = System.currentTimeMillis();
            log.info("获取用户可访问的单元ID列表完成，用户ID：{}，耗时：{}ms", userId, endTime - startTime);
            return Collections.emptyList();
            
        } catch (Exception e) {
            long endTime = System.currentTimeMillis();
            log.error("获取用户可访问的单元ID列表失败，用户ID：{}，耗时：{}ms", userId, endTime - startTime, e);
            return Collections.emptyList();
        }
    }
    
    @Override
    @Cacheable(value = "datascope:householdIds", key = "#userId", unless = "#result == null || #result.isEmpty()")
    public List<Long> getAccessibleHouseholdIds(Long userId) {
        long startTime = System.currentTimeMillis();
        log.info("获取用户可访问的房户ID列表，用户ID：{}", userId);
        
        try {
            // 参数验证
            if (userId == null) {
                log.warn("用户ID为空，返回空列表");
                return Collections.emptyList();
            }
            
            DataScopeInfo dataScopeInfo = dataScopeFeign.getUserDataScope(userId);
            if (dataScopeInfo == null) {
                log.warn("获取用户数据权限信息失败，用户ID：{}", userId);
                return Collections.emptyList();
            }
            
            List<Long> result = dataScopeInfo.getHouseholdIds() != null ? dataScopeInfo.getHouseholdIds() : Collections.emptyList();
            long endTime = System.currentTimeMillis();
            log.info("获取用户可访问的房户ID列表完成，用户ID：{}，数量：{}，耗时：{}ms", userId, result.size(), endTime - startTime);
            return result;
            
        } catch (Exception e) {
            long endTime = System.currentTimeMillis();
            log.error("获取用户可访问的房户ID列表失败，用户ID：{}，耗时：{}ms", userId, endTime - startTime, e);
            return Collections.emptyList();
        }
    }
    
    @Override
    @Cacheable(value = "datascope:regionPermission", key = "#userId + '_' + #regionId", unless = "#result == false")
    public boolean hasRegionPermission(Long userId, Long regionId) {
        long startTime = System.currentTimeMillis();
        log.info("检查用户是否有区域权限，用户ID：{}，区域ID：{}", userId, regionId);
        
        try {
            // 参数验证
            if (userId == null || regionId == null) {
                log.warn("用户ID或区域ID为空，返回false");
                return false;
            }
            
            DataScopeInfo dataScopeInfo = dataScopeFeign.getUserDataScope(userId);
            if (dataScopeInfo == null) {
                log.warn("获取用户数据权限信息失败，用户ID：{}", userId);
                return false;
            }
            
            // 超级管理员有所有权限
            if (dataScopeInfo.isSuperAdmin()) {
                long endTime = System.currentTimeMillis();
                log.info("超级管理员区域权限检查完成，用户ID：{}，区域ID：{}，耗时：{}ms", userId, regionId, endTime - startTime);
                return true;
            }
            
            // 这里应该检查用户是否有该区域的权限
            // 为了简化，暂时返回false
            long endTime = System.currentTimeMillis();
            log.info("检查用户区域权限完成，用户ID：{}，区域ID：{}，结果：false，耗时：{}ms", userId, regionId, endTime - startTime);
            return false;
            
        } catch (Exception e) {
            long endTime = System.currentTimeMillis();
            log.error("检查用户区域权限失败，用户ID：{}，区域ID：{}，耗时：{}ms", userId, regionId, endTime - startTime, e);
            return false;
        }
    }
    
    @Override
    @Cacheable(value = "datascope:communityPermission", key = "#userId + '_' + #communityId", unless = "#result == false")
    public boolean hasCommunityPermission(Long userId, Long communityId) {
        long startTime = System.currentTimeMillis();
        log.info("检查用户是否有社区权限，用户ID：{}，社区ID：{}", userId, communityId);
        
        try {
            // 参数验证
            if (userId == null || communityId == null) {
                log.warn("用户ID或社区ID为空，返回false");
                return false;
            }
            
            DataScopeInfo dataScopeInfo = dataScopeFeign.getUserDataScope(userId);
            if (dataScopeInfo == null) {
                log.warn("获取用户数据权限信息失败，用户ID：{}", userId);
                return false;
            }
            
            boolean result = dataScopeInfo.hasCommunityPermission(communityId);
            long endTime = System.currentTimeMillis();
            log.info("检查用户社区权限完成，用户ID：{}，社区ID：{}，结果：{}，耗时：{}ms", userId, communityId, result, endTime - startTime);
            return result;
            
        } catch (Exception e) {
            long endTime = System.currentTimeMillis();
            log.error("检查用户社区权限失败，用户ID：{}，社区ID：{}，耗时：{}ms", userId, communityId, endTime - startTime, e);
            return false;
        }
    }
    
    @Override
    @Cacheable(value = "datascope:buildingPermission", key = "#userId + '_' + #buildingId", unless = "#result == false")
    public boolean hasBuildingPermission(Long userId, Long buildingId) {
        long startTime = System.currentTimeMillis();
        log.info("检查用户是否有楼栋权限，用户ID：{}，楼栋ID：{}", userId, buildingId);
        
        try {
            // 参数验证
            if (userId == null || buildingId == null) {
                log.warn("用户ID或楼栋ID为空，返回false");
                return false;
            }
            
            DataScopeInfo dataScopeInfo = dataScopeFeign.getUserDataScope(userId);
            if (dataScopeInfo == null) {
                log.warn("获取用户数据权限信息失败，用户ID：{}", userId);
                return false;
            }
            
            // 超级管理员有所有权限
            if (dataScopeInfo.isSuperAdmin()) {
                long endTime = System.currentTimeMillis();
                log.info("超级管理员楼栋权限检查完成，用户ID：{}，楼栋ID：{}，耗时：{}ms", userId, buildingId, endTime - startTime);
                return true;
            }
            
            // 这里应该检查用户是否有该楼栋的权限
            // 为了简化，暂时返回false
            long endTime = System.currentTimeMillis();
            log.info("检查用户楼栋权限完成，用户ID：{}，楼栋ID：{}，结果：false，耗时：{}ms", userId, buildingId, endTime - startTime);
            return false;
            
        } catch (Exception e) {
            long endTime = System.currentTimeMillis();
            log.error("检查用户楼栋权限失败，用户ID：{}，楼栋ID：{}，耗时：{}ms", userId, buildingId, endTime - startTime, e);
            return false;
        }
    }
    
    @Override
    @Cacheable(value = "datascope:unitPermission", key = "#userId + '_' + #unitId", unless = "#result == false")
    public boolean hasUnitPermission(Long userId, Long unitId) {
        long startTime = System.currentTimeMillis();
        log.info("检查用户是否有单元权限，用户ID：{}，单元ID：{}", userId, unitId);
        
        try {
            // 参数验证
            if (userId == null || unitId == null) {
                log.warn("用户ID或单元ID为空，返回false");
                return false;
            }
            
            DataScopeInfo dataScopeInfo = dataScopeFeign.getUserDataScope(userId);
            if (dataScopeInfo == null) {
                log.warn("获取用户数据权限信息失败，用户ID：{}", userId);
                return false;
            }
            
            // 超级管理员有所有权限
            if (dataScopeInfo.isSuperAdmin()) {
                long endTime = System.currentTimeMillis();
                log.info("超级管理员单元权限检查完成，用户ID：{}，单元ID：{}，耗时：{}ms", userId, unitId, endTime - startTime);
                return true;
            }
            
            // 这里应该检查用户是否有该单元的权限
            // 为了简化，暂时返回false
            long endTime = System.currentTimeMillis();
            log.info("检查用户单元权限完成，用户ID：{}，单元ID：{}，结果：false，耗时：{}ms", userId, unitId, endTime - startTime);
            return false;
            
        } catch (Exception e) {
            long endTime = System.currentTimeMillis();
            log.error("检查用户单元权限失败，用户ID：{}，单元ID：{}，耗时：{}ms", userId, unitId, endTime - startTime, e);
            return false;
        }
    }
    
    @Override
    @Cacheable(value = "datascope:householdPermission", key = "#userId + '_' + #householdId", unless = "#result == false")
    public boolean hasHouseholdPermission(Long userId, Long householdId) {
        long startTime = System.currentTimeMillis();
        log.info("检查用户是否有房户权限，用户ID：{}，房户ID：{}", userId, householdId);
        
        try {
            // 参数验证
            if (userId == null || householdId == null) {
                log.warn("用户ID或房户ID为空，返回false");
                return false;
            }
            
            DataScopeInfo dataScopeInfo = dataScopeFeign.getUserDataScope(userId);
            if (dataScopeInfo == null) {
                log.warn("获取用户数据权限信息失败，用户ID：{}", userId);
                return false;
            }
            
            boolean result = dataScopeInfo.hasHouseholdPermission(householdId);
            long endTime = System.currentTimeMillis();
            log.info("检查用户房户权限完成，用户ID：{}，房户ID：{}，结果：{}，耗时：{}ms", userId, householdId, result, endTime - startTime);
            return result;
            
        } catch (Exception e) {
            long endTime = System.currentTimeMillis();
            log.error("检查用户房户权限失败，用户ID：{}，房户ID：{}，耗时：{}ms", userId, householdId, endTime - startTime, e);
            return false;
        }
    }
    
    @Override
    public boolean grantDataScope(Long userId, String scopeType, List<Long> scopeIds) {
        long startTime = System.currentTimeMillis();
        log.info("授权用户数据范围，用户ID：{}，范围类型：{}，范围ID列表：{}", userId, scopeType, scopeIds);
        
        try {
            // 参数验证
            if (userId == null || scopeType == null || scopeIds == null) {
                log.warn("授权参数无效，用户ID：{}，范围类型：{}，范围ID列表：{}", userId, scopeType, scopeIds);
                return false;
            }
            
            // 这里应该实现数据范围授权逻辑
            // 为了简化，暂时返回true
            long endTime = System.currentTimeMillis();
            log.info("授权用户数据范围完成，用户ID：{}，范围类型：{}，耗时：{}ms", userId, scopeType, endTime - startTime);
            return true;
            
        } catch (Exception e) {
            long endTime = System.currentTimeMillis();
            log.error("授权用户数据范围失败，用户ID：{}，范围类型：{}，耗时：{}ms", userId, scopeType, endTime - startTime, e);
            return false;
        }
    }
    
    /**
     * 获取用户数据权限信息
     * 这个方法是为了兼容OwnerHouseholdServiceImpl中的调用
     * 
     * 注意：移除@Cacheable注解，避免DataScopeInfo复杂对象序列化/反序列化时的ClassCastException问题
     * 复杂对象（如DataScopeInfo、自定义VO、复杂实体类等）在Redis缓存中容易出现类型转换错误
     * 遵循《Java后端SpringBoot代码开发规范.md》的缓存使用规范
     * 
     * @param userId 用户ID
     * @return 数据权限信息
     */
    public DataScopeInfo getUserDataScope(Long userId) {
        long startTime = System.currentTimeMillis();
        log.info("获取用户数据权限信息，用户ID：{}", userId);
        
        try {
            // 参数验证
            if (userId == null) {
                log.warn("用户ID为空，返回null");
                return null;
            }
            
            DataScopeInfo result = dataScopeFeign.getUserDataScope(userId);
            long endTime = System.currentTimeMillis();
            log.info("获取用户数据权限信息完成，用户ID：{}，耗时：{}ms", userId, endTime - startTime);
            return result;
        } catch (Exception e) {
            long endTime = System.currentTimeMillis();
            log.error("获取用户数据权限信息失败，用户ID：{}，耗时：{}ms", userId, endTime - startTime, e);
            return null;
        }
    }
}
